/**
 * APIFunction.java
 * ************************** 
 * @date Apr 18, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package infrastructureAPI.algorithms;

import infrastructureAPI.Service;
import infrastructureAPI.APIMessages.RequestMessage;

import java.io.Serializable;
import java.net.InetAddress;
import java.util.List;

/**
 * Description: 
 * An APIFunction represents a feature 
 * provided by the infrastructure layer of the cloud.
 * The overall set of the APIFunction(s), and so all the 
 * features, composes the API of the entire cloud.
 * Because all provided features refer to very different 
 * actions, we can suppose that each of them need a completely
 * different algorithm, or perhaps similar to one another
 * but only in a few shared parts.
 * Each APIFunction submits a request to the cloud that will
 * be satisfied once all the resources are available.
 * An APIFunction may also take advantage of some Service(s) offered
 * by the cloud.
 * An APIFunction is a Runnable object, so once the DispatcherSystem
 * collected a request it starts a Thread that will accomplish the algorithm.
 * An APIFunction is able to:
 * 	- perform its own algorithm,
 *	- list all required Service(s) needed to accomplish its 
 *	own actions,
 *	- build the RequestMessage that will be sent to the back-end
 *	of the cloud.
 * An APIFunction may also provide a new Service for the Cloud,
 * which may require the registration into a ServiceHandler.
 * An APIFunction may also require the de-registration of a 
 * running service, which has to be de-registered from the
 * ServiceHandler holding it.
 *	
 *
 */
public interface APIFunction extends Serializable, Runnable {
	
	/**
	 * Each APIFunction may need different Service(s). 
	 * The method initializeServices provides the verification
	 * and the initialization of the required services by the
	 * list in input.
	 * @return done : boolean
	 */
	public boolean initializeServices(List<Service> services);
	
	/**
	 * Defines the List of required Service(s) calling them by
	 * their Class<?> identity. Each Service registered into the 
	 * cloud is selected by its class belonging. 
	 * The DispatcherSystem will provide Service(s) in the same
	 * order defined by this function. 
	 * @return reqServices : List<Class<?>>
	 */
	public List<Class<?>> requiredServices();
	
	/**
	 * Returns the RequestMessage to be forwarded to the cloud
	 * in order to submit the current APIFunction as a request.
	 * @param targetAddress
	 * @param targetNodeName
	 * @return message : RequestMessage
	 */
	public RequestMessage createRequestMessage(InetAddress targetAddress, 
			String targetNodeName);
	
	/**
	 * The APIFunction may also become a {@link Service} for the
	 * higher levels of the node stack. 
	 * In order to be retrieved in future it need a registration
	 * into a ServiceHandler. 
	 * @return needRegistration : boolean
	 */
	public boolean requireSystemRegistration();
	
	/**
	 * An APIFunction that provides a new {@link Service} for higher
	 * levels has to expose its Service in order to be 
	 * registered into the system acting as a ServiceHandler.
	 * @return service : Service
	 */
	public Service extractSuppliedService();
	
	/**
	 * Returns true if this APIFunction needs to 
	 * de-register a Service from the actual 
	 * ServiceHandler.
	 * @return needDeRegistration : boolean
	 */
	public boolean requireSystemDeRegistration();
	
	/**
	 * Specifies the Service to be de-registered from the
	 * current ServiceHandler.
	 * @return service : Service
	 */
	public Service extractServiceToDeRegister();
	
	/**
	 * Indicates if this APIFunction need a reply to the
	 * node requester or not.
	 * @return needReply : boolean
	 */
	public boolean requireReply();
		
}
